home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / PROGRAMM / PASCAL / 0187.ZIP / WUMPUS.PAS < prev   
Pascal/Delphi Source File  |  1985-01-20  |  8KB  |  390 lines

  1. program wumpus;
  2.  
  3. const
  4.    maxrooms            = 20;
  5.    maxbats             = 2;
  6.    maxpits             = 2;
  7.    numberofarrows      = 7;
  8.    prompt              = '> ';
  9.    tunnelsperroom      = 2;
  10.    move                = 'M';
  11.    quit                = 'Q';
  12.    shoot               = 'S';
  13.    help                = '?';
  14.  
  15. type
  16.    room = 1..maxrooms;
  17.    rooms = set of room;
  18.  
  19. var
  20.    cave         : array[room] of rooms;
  21.    player       : room;
  22.    wumpus       : room;
  23.    arrowsleft   : integer;
  24.    quitting     : boolean;
  25.    killed       : boolean;
  26.    wumpuskilled : boolean;
  27.    bats         : rooms;
  28.    pits         : rooms;
  29.    commandset   : set of char;
  30.  
  31. (*
  32.  * rand
  33.  * returns a random number between low and high
  34.  *)
  35.  
  36. function rand(low, high : integer) : integer;
  37.  
  38. begin
  39.    rand := low + random(high-low+1);
  40. end;
  41.  
  42. procedure doinstr;
  43.  
  44. begin
  45.    writeln;
  46.    writeln('Your mission, should you desire to accept it, is it hunt for the');
  47.    writeln('Wumpus in his cave. To succeed, you must shoot it with one of your');
  48.    writeln(numberofarrows:1,' arrows. If you shoot into a room which is not directly connected to');
  49.    writeln('yours, the arrow will bounce to one of the rooms that does connect.');
  50.    writeln('The bats in the cave may pick you up and place you in a different');
  51.    writeln('room. If you enter a room which has a pit, you will fall into it.');
  52.    writeln('If the wumpus finds you or you run out of arrows, you lose.');
  53.    writeln;
  54. end;
  55.  
  56. procedure askinstruct;
  57.  
  58. var
  59.    answer : char;
  60.  
  61. begin
  62.    write('Do you want instructions? ');
  63.    readln(answer);
  64.    while (answer <> 'y') and (answer <> 'Y') and (answer <> 'n') and (answer <> 'N') do
  65.       begin
  66.       writeln('Please answer yes or no');
  67.       write('Would you like instructions? ');
  68.       readln(answer);
  69.       end;
  70.    if (answer = 'y') or (answer = 'Y') then
  71.       doinstr;
  72. end;
  73.  
  74. (*
  75.  * addtunnel
  76.  * make a tunnel connection between two rooms
  77.  *)
  78.  
  79. procedure addtunnel(from, dest : room);
  80.  
  81. begin
  82.    cave[from] := cave[from] + [dest];
  83.    cave[dest] := cave[dest] + [from];
  84. end;
  85.  
  86. (*
  87.  * makemaze
  88.  * makes a reasonably random maze. for each room tries to make 3 new tunnels.
  89.  * if a tunnel already exists in that direction, another digging that way is
  90.  * not made.
  91.  *)
  92.  
  93. procedure makemaze;
  94.  
  95. var
  96.    currentroom, tunnelto, newtunnel : room;
  97.  
  98. begin
  99.    for currentroom := 2 to maxrooms do
  100.       addtunnel(currentroom, currentroom-1);
  101.    for currentroom := 3 to maxrooms do
  102.       begin
  103.       newtunnel := rand(1, currentroom-1);
  104.       if not newtunnel in cave[currentroom] then
  105.          addtunnel(currentroom, newtunnel);
  106.       end;
  107. end;
  108.  
  109. (*
  110.  * skipblanks
  111.  * skips spaces, tabs until eoln
  112.  *)
  113.  
  114. procedure skipblanks;
  115.  
  116.  
  117. begin
  118. end;
  119.  
  120. (*
  121.  * describe
  122.  * give a description of the current room ( player ). tell player if the
  123.  * wumpus is nearby.
  124.  *)
  125.  
  126. procedure describe;
  127.  
  128. var
  129.    i : room;
  130.  
  131. begin
  132.    writeln('You are in room ',player:1);
  133.    write('There are tunnels leading to rooms');
  134.    for i := 1 to maxrooms do
  135.       if i in cave[player] then
  136.          write(' ',i:1);
  137.    writeln;
  138.    if (player in cave[wumpus]) or ((cave[player] * cave[wumpus]) <> []) then
  139.       writeln('I smell a Wumpus.');
  140.    if cave[player] * bats <> [] then
  141.       writeln('I hear bats.');
  142.    if cave[player] * pits <> [] then
  143.       writeln('I feel a draft.');
  144. end;
  145.  
  146. (*
  147.  * command
  148.  * returns the single character that signifies what is to be done
  149.  *)
  150.  
  151. function command : char;
  152.  
  153. var
  154.    ch : char;
  155.  
  156. begin
  157.    describe;
  158.    repeat
  159.       write(prompt);
  160.       readln(ch);
  161.       if not (ch in commandset) then
  162.          begin
  163.          writeln(' Type ? for instructions.');
  164.          end;
  165.    until ch in commandset;
  166.    command := ch;
  167. end;
  168.  
  169. (*
  170.  * checkwump
  171.  * move the wumpus and see if it went to the same room as the player,
  172.  * if so he's dead.
  173.  *)
  174.  
  175. procedure checkwump;
  176.  
  177. var
  178.    newwumproom : room;
  179.  
  180. begin
  181.    newwumproom := rand(1, maxrooms);
  182.    if (newwumproom in cave[wumpus]) then
  183.       wumpus := newwumproom;
  184.    if (wumpus = player) then
  185.       begin
  186.       writeln('Look Out!! The Wumpus got you.');
  187.       writeln('Better luck next time.');
  188.       killed := true;
  189.       end;
  190. end;
  191.  
  192. (*
  193.  * checkbats
  194.  * if the player is in a room with bats they will pick him up and move him to
  195.  * another room (which will not have bats in it).
  196.  *)
  197.  
  198. procedure checkbats;
  199.  
  200. var
  201.    flewto : room;
  202.  
  203. begin
  204.    if player in bats then
  205.       begin
  206.       repeat
  207.          flewto := rand(1,maxrooms)
  208.       until (not (flewto in (bats + pits))) and (flewto <> wumpus);
  209.       writeln('A superbat picked you up and carried you off.');
  210.       player := flewto;
  211.       end;
  212. end;
  213.  
  214. (*
  215.  * checkpits
  216.  * determines if the player fell into a pit.
  217.  *)
  218.  
  219. procedure checkpits;
  220.  
  221. begin
  222.    if not killed and (player in pits) then
  223.       begin
  224.       writeln('Don''t do that!! Too late, you fell into a pit.');
  225.       writeln('You should be more careful.');
  226.       killed := true;
  227.       end;
  228. end;
  229.  
  230. (*
  231.  * randroom
  232.  * returns a random room number in the range limited by the set argument.
  233.  *)
  234.  
  235. function randroom ( limitedto : rooms) : integer;
  236.  
  237. var
  238.    apossibility : room;
  239.  
  240. begin
  241.    repeat
  242.       apossibility := rand(1, maxrooms);
  243.    until apossibility in limitedto;
  244.    randroom := apossibility;
  245. end;
  246.  
  247. (*
  248.  * doshoot
  249.  * player tries to shoot the wumpus by listing the rooms that he wants to
  250.  * shoot through. if the rooms do not match the list, the arrow bounces
  251.  * randomly to a connecting tunnel.
  252.  *)
  253.  
  254. procedure doshoot;
  255.  
  256. var
  257.    nextroom, lastroom : room;
  258.  
  259. begin
  260.    lastroom := player;
  261.    while not eoln do
  262.       begin
  263.       write('where ');
  264.       readln(nextroom);
  265.       if wumpus = nextroom then
  266.          wumpuskilled := true
  267.       else if player = nextroom then
  268.          killed := true;
  269.       if not (nextroom in cave[lastroom]) then
  270.          nextroom := randroom(cave[lastroom]);
  271.       lastroom := nextroom;
  272.       skipblanks;
  273.       end;
  274.    arrowsleft := arrowsleft - 1;
  275.    if killed then
  276.       writeln('You klutz! You just shot yourself.')
  277.    else if wumpuskilled then
  278.       writeln('Congratulations! You slew the fearsome Wumpus.')
  279.    else if arrowsleft = 0 then
  280.       writeln('You ran out of arrows.')
  281. end;
  282.  
  283. (*
  284.  * domove
  285.  * player's move, must be to an adjacent room
  286.  *)
  287.  
  288. procedure domove;
  289.  
  290. var
  291.    dest : room;
  292.  
  293. begin
  294.    write('To ');
  295.    readln(dest);
  296.    if not (dest in [1..maxrooms]) then
  297.       writeln('There is no room # ', dest)
  298.    else if not (dest in cave[player]) then
  299.       writeln('I see no tunnel to room # ',dest)
  300.    else
  301.       player := dest;
  302.    checkbats;
  303.    checkwump;
  304.    checkpits;
  305. end;
  306.  
  307. (*
  308.  * doquit
  309.  * asks if the player really wants to quit
  310.  *)
  311.  
  312. procedure doquit;
  313.  
  314. var
  315.    answer : char;
  316.  
  317. begin
  318.    writeln;
  319.    write('Do you really want to quit now? ');
  320.    readln(answer);
  321.    quitting := answer in ['y','Y'];
  322. end;
  323.  
  324. procedure doaturn(action : char);
  325.  
  326. begin
  327.    case action of
  328.       move  : domove;
  329.       shoot : doshoot;
  330.       quit  : doquit;
  331.       help  : doinstr;
  332.       end;
  333. end;
  334.  
  335. (*
  336.  * gameover
  337.  * returns true if the game is over
  338.  *)
  339.  
  340. function gameover : boolean;
  341.  
  342. begin
  343.    gameover := quitting or killed or wumpuskilled or (arrowsleft = 0);
  344. end;
  345.  
  346. (*
  347.  * initialize
  348.  * generates a random maze and the positions of the player, wumpus,and bats.
  349.  * make sure that the player doesn't start with the wumpus.
  350.  *)
  351.  
  352. procedure initialize;
  353.  
  354. var
  355.    i : room;
  356.  
  357. begin
  358.    randomize;
  359.    for i := 1 to maxrooms do
  360.       cave[i] := [];
  361.    bats := [];
  362.    pits := [];
  363.    makemaze;
  364.    wumpus := rand(1, maxrooms);
  365.    for i := 1 to maxbats do
  366.       bats := bats + [rand(1, maxrooms)];
  367.    for i := 1 to maxpits do
  368.       pits := pits + [rand(1, maxrooms)];
  369.    repeat
  370.       player := rand(1, maxrooms);
  371.    until (player <> wumpus) and not (player in pits) and not (player in bats);
  372.    quitting := false;
  373.    killed := false;
  374.    wumpuskilled := false;
  375.    arrowsleft := numberofarrows;
  376.    commandset := [move, shoot, quit, help];
  377. end;
  378.  
  379. begin
  380.    writeln('Welcome to Wumpus!!');
  381.    askinstruct;
  382.    initialize;
  383.    repeat
  384.       doaturn(command);
  385.    until gameover;
  386. end.
  387.  
  388.  
  389.  
  390.